var Slideshow = new Class({
	version: "0.5",
	slideshow_size: { width:0, height:0 },
	padding: 10,
	resize_on_load: true,
	slideshow_background: "transparent",
	show_nav: true,
	show_descriptions: true,
	description_template: "#{description}", // This doesn't work with moo?
	auto_play: false,
	timer_delay: 5,
	auto_size: false,
	auto_center: false,
	is_images: true,
	remove_twenty: true,
	size_by_images: true, // do I really need this?
	is_vertical: false,
	timer_id: 0,
	is_playing: false,
	objects_list: {},
	objects_amount: 0,
	current_object: 0,
	element_id: "",
	element: {},
	proxy_pos: 0,
	proxy_string: "",
	list_id: "",
	list: {},
	auto_size_dimensions: { width:0, height:0 },
	transition_object: {},
	initialize: function(element) {
		this.proxy_pos = Slideshows.push(this);
		this.proxy_string = "Slideshows.list["+this.proxy_pos+"]";
		this.element_id = element;
		this.element = $(element);
		this.list_id = $$('#'+element+' ul')[0].id;
		this.list = $(this.list_id);
		this.transition_object = new Slide(this);
		if (this.element.hasClass('vertical')) { 
			this.is_vertical = true; 
		} else if (!this.element.hasClass('horizontal')) {
			this.element.addClass('horizontal'); // default to horizontal
		}
	},
	build: function() {
		this.element.setStyle('overflow', 'hidden');
		// TODO: this all needs to be wrapped up in some dom load stuff!!!
		if (!this.is_images) { this.show_descriptions = false; }
		this.objects_list = this.generate_objects_list();
		// this is where the description template was built and saved with prototype
		this.resize();
		this.set_nav_code();
		this.mark_and_update(0);
		if (this.auto_play) { this.start(); }
	},
	next: function() {
		if (this.current_object == this.objects_amount-1) {
			this.wrap_transition(0);
		} else {
			this.wrap_transition(this.current_object+1);
		}
	},
	previous: function() {
		if (this.current_object == 0) {
			this.wrap_transition(this.objects_amount-1);
		} else {
			this.wrap_transition(this.current_object-1);
		}
	},
	transition: function(number) {
		this.transition_object.go_to(number);
	},
	wrap_transition: function(number) {
		if (this.current_object == number) { return false; }
		
		this.before_transition(number);
		this.transition(number);
		this.after_transition(number);
		
		this.current_object = number;
		return this.mark_and_update(number);
	},
	after_transition: function(number) { return true; }, // you can override this 
	before_transition: function(number) { return true; }, // you can override this
	mark_and_update: function(number) {
		if (this.show_descriptions) {
			$('slideshow-description-'+this.proxy_pos).setText(this.objects_list.alts[number]); 
			// eventually use the text templates like before
		}
		// eventually this will update the list of buttons for selecting a slide
		return number;
	},
	resize: function() {
		if (this.slideshow_size.height != 0) { 
			this.element.setStyle('height', this.slideshow_size.height);
			if (!this.is_vertical) { this.list.setStyle('height', this.slideshow_size.height); }
			this.remove_twenty = false;
			this.auto_size = false;
		}
		if (this.slideshow_size.width != 0) { 
			this.element.setStyle('width', this.slideshow_size.width);
			if (this.is_vertical) { this.list.setStyle('width', this.slideshow_size.width); }
			this.remove_twenty = false;
			this.auto_size = false;
		}
		
		if (this.is_vertical && this.remove_twenty) {
			this.element.setStyle('width', this.element.getStyle('width').toInt()-20);
		} else if (this.remove_twenty) {
			this.element.setStyle('height', this.element.getStyle('height').toInt()-20);
		}
		
		if (this.auto_size) { 
			this.element.setStyle('width', this.auto_size_dimensions.width);
			this.element.setStyle('height', this.auto_size_dimensions.height);
			
			if (this.is_vertical) {
				this.list.setStyle('width', this.auto_size_dimensions.width);
			} else {
				this.list.setStyle('height', this.auto_size_dimensions.height);
			}
		}
		this.element.setStyle('background', this.slideshow_background);
	},
	generate_objects_list: function() {
		positions_array = [0];
		alts_array = [];
		widths_array = [];
		heights_array = [];
		filenames_array = [];
		current_position = 0;
		padding = this.padding;
		is_vertical = this.is_vertical;
		auto_center = this.auto_center;
		
		biggest_width = 0;
		biggest_height = 0;
		
		objects = $$('#'+this.element_id+' li');
		
		objects.each(function(e) {
			width = e.getStyle('width').toInt();
			height = e.getStyle('height').toInt();
			
			if (is_vertical) { next_pos = height; } else { next_pos = width; }
			
			current_position += next_pos + padding;
			
			if (width > biggest_width) { biggest_width = width; }
			if (height > biggest_height) { biggest_height = height; }
			
			positions_array.push(-current_position);
			widths_array.push(width);
			heights_array.push(height);
			filenames_array.push(""); // just so it exists
			alts_array.push(""); // just so it exists
		});
		
		if (this.auto_size) {
			positions_array = [0]; // reset
			current_position = 0;
			objects.each(function(e) {
				e.setStyle('width', biggest_width);
				e.setStyle('height', biggest_height);
				
				if (this.is_vertical) { next_pos = biggest_height; } else { next_pos = biggest_width; }
				
				current_position += next_pos + padding;
				positions_array.push(-current_position);
			});
			
		}
		
		if (this.is_images) {
			images = $$('#'+this.element_id+' img');
			filenames_array = []; // reset
			alts_array = []; // reset
			
			images.each(function(e) {
				filename = e.src.split('/');
				filenames_array.push(filename[filename.length-1]);
				alts_array.push(e.alt);
				
				if (auto_center) {
					half_height = Math.floor( (biggest_height-e.getSize().size.y)/2 );
					e.getParent().setStyle('text-align', 'center');
					e.setStyle('margin', half_height+'px auto');
				}
			});
		}
		
		this.objects_amount = alts_array.length;
		
		this.auto_size_dimensions.width = biggest_width;
		this.auto_size_dimensions.height = biggest_height;
		
		return new ObjectList(positions_array, alts_array, widths_array, heights_array, filenames_array);
	},
	start: function() {
		this.timer_id = setInterval(this.proxy_string+'.next();', this.timer_delay*1000);
		if (this.show_nav && this.auto_play) {
			$('slideshow-play-stop-'+this.proxy_pos).removeClass('slideshow-play-only');
			$('slideshow-play-stop-'+this.proxy_pos).addClass('slideshow-stop-only');
		}
		this.is_playing = false;
	},
	stop: function() {
		clearInterval(this.timer_id);
		if (this.show_nav && this.auto_play) {
			$('slideshow-play-stop-'+this.proxy_pos).addClass('slideshow-play-only');
			$('slideshow-play-stop-'+this.proxy_pos).removeClass('slideshow-stop-only');
		}
		this.is_playing = false;
	},
	toggle: function() {
		if (this.is_playing) { this.stop(); } else { this.start(); }
	},
	next_and_stop: function() {
		this.stop();
		this.next();
	},
	previous_and_stop: function() {
		this.stop();
		this.previous();
	},
	set_nav_code: function() {
		if (!this.show_descriptions && !this.show_nav) { return false; }
		
		if (this.show_nav) {
			nav_bar = new Element('div', {
				'class': 'slideshow-nav',
				'id': 'slideshow-nav-'+this.proxy_pos
			});
			
			if (this.auto_play) {
				play_stop_buttons = new Element('div', {
					'class': 'slideshow-play-stop',
					'id': 'slideshow-play-stop-'+this.proxy_pos
				});
				new Element('a', {
					'href': '#',
					'class': 'slideshow-stop',
					'onclick': this.proxy_string+'.stop(); return false'
				}).setText('Stop').injectInside(play_stop_buttons);
				new Element('a', {
					'href': '#',
					'class': 'slideshow-play',
					'onclick': this.proxy_string+'.start(); return false'
				}).setText('Play').injectInside(play_stop_buttons);
				
				play_stop_buttons.injectInside(nav_bar);
			}
			
			next_prev_buttons = new Element('div', { 'class': 'slideshow-next-prev' });
			new Element('a', {
				'href': '#',
				'class': 'slideshow-prev',
				'onclick': this.proxy_string+'.previous_and_stop(); return false'
			}).setText('Previous').injectInside(next_prev_buttons);
			new Element('a', {
				'href': '#',
				'class': 'slideshow-next',
				'onclick': this.proxy_string+'.next_and_stop(); return false'
			}).setText('Next').injectInside(next_prev_buttons);
			
			next_prev_buttons.injectInside(nav_bar);
			
			if (this.auto_size) { nav_bar.setStyle('width', this.auto_size_dimensions.width); }
			if (this.slideshow_size.width != 0) { nav_bar.setStyle('width', this.slideshow_size.width); }
			
			nav_bar.injectAfter(this.element);
		}
		
		if (this.show_descriptions) {
			description = new Element('div', {
				'class': 'slideshow-description',
				'id': 'slideshow-description-'+this.proxy_pos
			}).setText('');
			if (this.auto_size) { description.setStyle('width', this.auto_size_dimensions.width-10); } // this needs to be more flexable (the 10 part)
			description.injectAfter(this.element);
		}
	}
});

var Slide = new Class({
	is_animating: false,
	slideshow: {},
	ul: {},
	speed: 750,
	fx: {},
	initialize: function(slideshow) {
		this.slideshow = slideshow;
		this.fx = new Fx.Scroll(this.slideshow.element, { wait: false, duration: this.speed, wheelStops: false, transition: Fx.Transitions.Quart.easeOut });
	},
	go_to: function(number) {
		new_position = this.slideshow.objects_list.positions[number];
		if (this.slideshow.is_vertical) {
			this.fx.scrollTo(0, -new_position);
		} else {
			this.fx.scrollTo(-new_position, 0);
		}
	}
});

var ObjectList = new Class({
	widths: [],
	heights: [],
	positions: [],
	alts: [],
	filenames: [],
	initialize: function(positions, alts, widths, heights, filenames) {
		this.positions = positions;
		this.alts = alts;
		this.widths = widths;
		this.heights = heights;
		this.filenames = filenames;
	}
});

var Slideshows = {
	list: [],
	push: function(slideshow) {
		current_pos = Slideshows.list.length;
		Slideshows.list.push(slideshow);
		return current_pos;
	}
};